﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using MessagePack.Formatters;

namespace MessagePack.Internal
{
	// Token: 0x02000115 RID: 277
	internal static class DynamicPrivateFormatterBuilder
	{
		// Token: 0x060003FE RID: 1022 RVA: 0x00010A44 File Offset: 0x0000EE44
		public static object BuildFormatter(Type type)
		{
			return null;
		}

		// Token: 0x060003FF RID: 1023 RVA: 0x00010CF0 File Offset: 0x0000F0F0
		private static void EmitOffsetPlusEqual(ILGenerator il, Action loadEmit, Action emit)
		{
			il.EmitLdarg(1);
			if (loadEmit != null)
			{
				loadEmit();
			}
			il.EmitLdarg(0);
			il.EmitLdarg(1);
			emit();
			il.Emit(OpCodes.Add);
			il.EmitStarg(1);
		}

		// Token: 0x06000400 RID: 1024 RVA: 0x00010D2C File Offset: 0x0000F12C
		private static void EmitSerializeValue(ILGenerator il, TypeInfo_wzh type, ObjectSerializationInfo.EmittableMember member)
		{
			Type t = member.Type;
			if (DynamicPrivateFormatterBuilder.IsOptimizeTargetType(t))
			{
				DynamicPrivateFormatterBuilder.EmitOffsetPlusEqual(il, null, delegate
				{
					il.EmitLoadArg(type, 2);
					member.EmitLoadValue(il);
					if (t == typeof(byte[]))
					{
						il.EmitCall(DynamicObjectTypeBuilder.MessagePackBinaryTypeInfo.WriteBytes);
					}
					else
					{
						il.EmitCall(DynamicObjectTypeBuilder.MessagePackBinaryTypeInfo.TypeInfo.GetDeclaredMethod("Write" + t.Name));
					}
				});
			}
			else
			{
				DynamicPrivateFormatterBuilder.EmitOffsetPlusEqual(il, delegate
				{
					il.EmitLdarg(3);
					il.Emit(OpCodes.Call, DynamicPrivateFormatterBuilder.getFormatterWithVerify.MakeGenericMethod(new Type[]
					{
						t
					}));
				}, delegate
				{
					il.EmitLoadArg(type, 2);
					member.EmitLoadValue(il);
					il.EmitLdarg(3);
					il.EmitCall(DynamicPrivateFormatterBuilder.getSerialize(t));
				});
			}
		}

		// Token: 0x06000401 RID: 1025 RVA: 0x00010DB8 File Offset: 0x0000F1B8
		private static bool IsOptimizeTargetType(Type type)
		{
			return type == typeof(short) || type == typeof(int) || type == typeof(long) || type == typeof(ushort) || type == typeof(uint) || type == typeof(ulong) || type == typeof(float) || type == typeof(double) || type == typeof(bool) || type == typeof(byte) || type == typeof(sbyte) || type == typeof(char);
		}

		// Token: 0x040001A2 RID: 418
		private static readonly Type refByte = typeof(byte[]).MakeByRefType();

		// Token: 0x040001A3 RID: 419
		private static readonly MethodInfo getFormatterWithVerify = typeof(FormatterResolverExtensions).GetRuntimeMethods().First((MethodInfo x) => x.Name == "GetFormatterWithVerify");

		// Token: 0x040001A4 RID: 420
		private static readonly Func<Type, MethodInfo> getSerialize = (Type t) => typeof(IMessagePackFormatter<>).MakeGenericType(new Type[]
		{
			t
		}).GetRuntimeMethod("Serialize", new Type[]
		{
			DynamicPrivateFormatterBuilder.refByte,
			typeof(int),
			t,
			typeof(IFormatterResolver)
		});
	}
}
